package org.yeasy.cud.util;

import cn.hutool.core.util.ReflectUtil;
import org.yeasy.common.util.CommonBeanUtil;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * The type My list util.
 *
 * @author yangyishe
 * @date 2022年05月10日 16:06
 */
public class BeanListUtil {

    private static final String DEFAULT_ID_FIELD = "id";

    private final static String SETTER_ID_METHOD_NAME = "setId";

    /**
     * Distinct list.
     *
     * @param <T>       the type parameter
     * @param tList     the t list
     * @param fieldName the field name
     * @return the list
     * @author yangyishe
     * @date 2023年02月03日 10:07
     */
    public static <T extends Serializable> List<T> distinct(List<T> tList, String fieldName) {
        Map<String, T> mapKey2T = new HashMap<>();
        for (T t : tList) {
            String key = CommonBeanUtil.invokeGetter(t, fieldName);
            mapKey2T.putIfAbsent(key, t);
        }
        return new ArrayList<>(mapKey2T.values());
    }


    /**
     * Fill id.批量填充id
     *
     * @param <T>    the type parameter
     * @param c      the c
     * @param lstObj the lst obj
     * @author YangYishe
     * @date 2021年07月13日 09:40
     */
    public static <T> void fillBatchId(Class<T> c, List<T> lstObj) {
        if (lstObj.isEmpty()) {
            return;
        }
        List<Long> lstId = IdUtil.nextBatchId(lstObj.size());
        int intIndex = 0;
        for (T t : lstObj) {
            Method[] arrSetIdMethod = c.getDeclaredMethods();
            for (Method method : arrSetIdMethod) {
                if (method.getName().equals(SETTER_ID_METHOD_NAME)) {
                    //根据参数确定是哪种类型:Long或者String
                    if (String.class.equals(method.getParameterTypes()[0])) {
                        ReflectUtil.invoke(t, method, lstId.get(intIndex++).toString());
                    } else {
                        ReflectUtil.invoke(t, method, lstId.get(intIndex++));
                    }
                }
            }
        }
    }

    /**
     * Fill batch id.默认id类型为Long
     *
     * @param <T>   the type parameter
     * @param tList the t list
     * @author yangyishe
     * @date 2022年10月21日 11:38
     */
    public static <T> void fillBatchId(List<T> tList) {
        if (tList.isEmpty()) {
            return;
        }
        List<Long> lstId = IdUtil.nextBatchId(tList.size());
        int intIndex = 0;
        for (T t : tList) {
            CommonBeanUtil.invokeSetter(t, DEFAULT_ID_FIELD, lstId.get(intIndex++));
        }
    }

    /**
     * Fill batch info.批量填充信息
     *
     * @param <T>        the type parameter
     * @param <V>        the type parameter
     * @param tList      the t list
     * @param valueField the value field
     * @param value      the value
     * @author yangyishe
     * @date 2022年10月21日 11:33
     */
    public static <T, V> void fillBatchInfo(List<T> tList, String valueField, V value) {
        for (T t : tList) {
            CommonBeanUtil.invokeSetter(t, valueField, value);
        }
    }

    /**
     * Trans to start end int [ ].
     * 转换开始和结束的row
     *
     * @param pageNum   the page num
     * @param pageSize  the page size
     * @param totalSize the total size
     * @return the int [ ]
     * @author YangYishe
     * @date 2022年03月09日 10:38
     */
    public static int[] transToStartEnd(int pageNum, int pageSize, int totalSize) {
        if (pageSize * pageNum > (totalSize + pageSize)) {
            pageNum = 1;
        }
        int intStartNum = (pageNum - 1) * pageSize;
        int intEndNum = pageNum * pageSize;
        return new int[]{intStartNum, intEndNum};
    }
}
